home *** CD-ROM | disk | FTP | other *** search
/ The Guided Tour of Multimedia (Second Edition) / The Guided Tour of Multimedia (Second Edition).iso / trials / qtw111 / samples / stereo.c < prev    next >
C/C++ Source or Header  |  1992-10-23  |  13KB  |  430 lines

  1.  
  2. // ---------------------------------------------------------------------
  3. //
  4. // Stereo.c - Sample QuickTime for Windows Application
  5. //
  6. //            (c) 1988-1992 Apple Computer, Inc. All Rights Reserved.
  7. //
  8. // ---------------------------------------------------------------------
  9.  
  10. #include <windows.h>
  11. #include <commdlg.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <direct.h>
  15. #include <qtw.h>
  16. #include "stereo.h"
  17.  
  18. #ifdef __BORLANDC__
  19.    #define _getcwd getcwd
  20. #endif
  21.  
  22. long FAR PASCAL __export WndProc (HWND, UINT, WPARAM, LPARAM);
  23. VOID CalcSize (HWND);
  24.  
  25. RECT rcLeft, rcRight, rcMovieBox, rcClient;
  26. MovieController mcLeft, mcRight, mcActive;
  27.  
  28. int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  29.    LPSTR lpszCmdParam, int nCmdShow)
  30.    {
  31.    static char szAppName [] = "Stereo";
  32.    HWND        hWnd;
  33.    MSG         msg;
  34.    WNDCLASS    wndclass;
  35.  
  36. // Establish links to QuickTime for Windows
  37.  
  38.    if (QTInitialize (NULL))
  39.       {
  40.       MessageBox (NULL, "QTInitialize failure", szAppName, MB_OK);
  41.       return 0;
  42.       }
  43.  
  44. // Allocate memory required for playing movies
  45.  
  46.    if (EnterMovies ())
  47.       {
  48.       MessageBox (NULL, "EnterMovies failure", szAppName, MB_OK);
  49.       return 0;
  50.       }
  51.  
  52. // Register and create main window
  53.  
  54.    if (!hPrevInstance)
  55.       {
  56.       wndclass.style         = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
  57.       wndclass.lpfnWndProc   = WndProc;
  58.       wndclass.cbClsExtra    = 0;
  59.       wndclass.cbWndExtra    = 0;
  60.       wndclass.hInstance     = hInstance;
  61.       wndclass.hIcon         = LoadIcon (NULL,IDI_APPLICATION);
  62.       wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  63.       wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  64.       wndclass.lpszMenuName  = szAppName;
  65.       wndclass.lpszClassName = szAppName;
  66.  
  67.       if (!RegisterClass (&wndclass))
  68.          {
  69.          MessageBox (NULL, "RegisterClass failure", szAppName, MB_OK);
  70.          return 0;
  71.          }
  72.       }
  73.  
  74.    hWnd = CreateWindow (szAppName, szAppName, WS_OVERLAPPEDWINDOW |
  75.       WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  76.       CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
  77.  
  78.    if (hWnd == NULL)
  79.       {
  80.       MessageBox (NULL, "CreateWindow failure", szAppName, MB_OK);
  81.       return 0;
  82.       }
  83.  
  84. // Show the main window
  85.  
  86.    ShowWindow (hWnd, nCmdShow);
  87.    UpdateWindow (hWnd);
  88.  
  89. // Play the movies
  90.  
  91.    while (GetMessage (&msg, NULL, 0, 0))
  92.       {
  93.       TranslateMessage (&msg);
  94.       DispatchMessage (&msg);
  95.       }
  96.  
  97. // Cut the connections to QuickTime for Windows
  98.  
  99.    ExitMovies ();
  100.    QTTerminate ();
  101.  
  102. // Return to Windows
  103.  
  104.    return msg.wParam;
  105.    }
  106.  
  107.  
  108. long FAR PASCAL __export WndProc (HWND hWnd, UINT message, WPARAM wParam,
  109.    LPARAM lParam)
  110.    {
  111.    OPENFILENAME ofn;
  112.    PAINTSTRUCT ps;
  113.    BOOL bLeft;
  114.    POINT ptMovie;
  115.    MovieFile mfMovie;
  116.  
  117.    static Movie mLeft, mRight;
  118.  
  119.    static char szDirName [256];
  120.    static char szFile [256];
  121.    static char szFileTitle [256];
  122.  
  123. // Drive the movie controllers
  124.  
  125.    if (MCIsPlayerMessage (mcLeft, hWnd, message, wParam, lParam)
  126.     || MCIsPlayerMessage (mcRight, hWnd, message, wParam, lParam))
  127.       return 0;
  128.  
  129. // Process window messages
  130.  
  131.    switch (message)
  132.       {
  133.  
  134.    // Create empty movie controllers when main window is created
  135.  
  136.       case WM_CREATE:
  137.  
  138.          SetRectEmpty (&rcMovieBox);
  139.          SetRectEmpty (&rcClient);
  140.  
  141.          mcLeft = NewMovieController (NULL, &rcClient,
  142.             mcNotVisible, hWnd);
  143.          mcRight = NewMovieController (NULL, &rcClient,
  144.             mcNotVisible, hWnd);
  145.          return 0;
  146.  
  147.    // Process menu commands
  148.  
  149.       case WM_COMMAND:
  150.  
  151.          switch (wParam)
  152.             {
  153.  
  154.       // Use COMMDLG to open a movie file
  155.  
  156.             case IDM_OPEN:
  157.  
  158.                memset (&ofn, 0, sizeof (ofn));
  159.                ofn.lStructSize = sizeof (ofn);
  160.                ofn.hwndOwner = hWnd;
  161.                ofn.lpstrFilter = "Movies (*.mov)\0*.mov\0\0";
  162.                ofn.nFilterIndex = 1;
  163.                ofn.lpstrFile = szFile;
  164.                ofn.nMaxFile = sizeof (szFile);
  165.                ofn.lpstrFileTitle = szFileTitle;
  166.                ofn.nMaxFileTitle = sizeof (szFileTitle);
  167.                ofn.lpstrInitialDir =
  168.                   _getcwd (szDirName, sizeof (szDirName));
  169.                ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
  170.  
  171.                if (GetOpenFileName (&ofn) &&
  172.                   (OpenMovieFile (ofn.lpstrFile, &mfMovie, OF_READ) == noErr))
  173.                   {
  174.                   RECT rcGrowBox;
  175.  
  176.                // Dispose of any existing movies
  177.  
  178.                   DisposeMovie (mLeft);
  179.                   DisposeMovie (mRight);
  180.  
  181.                // Extract two instances of the same movie
  182.  
  183.                   NewMovieFromFile (&mLeft, mfMovie, NULL, NULL,
  184.                      0, NULL);
  185.                   NewMovieFromFile (&mRight, mfMovie, NULL, NULL,
  186.                      0, NULL);
  187.                   CloseMovieFile (mfMovie);
  188.  
  189.                // Get the normal dimensions of the movie
  190.  
  191.                   GetMovieBox (mLeft, &rcMovieBox);
  192.                   OffsetRect (&rcMovieBox, -rcMovieBox.left,
  193.                      -rcMovieBox.top);
  194.  
  195.                // Calculate initial positions of controllers
  196.  
  197.                   GetClientRect (hWnd, &rcClient);
  198.                   rcLeft.top = rcRight.top = rcClient.top +
  199.                     (rcClient.bottom / 2) - (rcMovieBox.bottom / 2);
  200.                   rcLeft.bottom = rcRight.bottom = rcClient.top +
  201.                     (rcClient.bottom / 2) + (rcMovieBox.bottom / 2);
  202.                   rcLeft.left = (rcClient.right / 4)
  203.                     - (rcMovieBox.right / 2);
  204.                   rcLeft.right = rcLeft.left + rcMovieBox.right;
  205.                   rcRight.left = (rcClient.right / 2)
  206.                     + (rcClient.right / 4)
  207.                     - (rcMovieBox.right / 2);
  208.                   rcRight.right = rcRight.left + rcMovieBox.right;
  209.  
  210.                // Associate the movies with the existing controllers
  211.  
  212.                   ptMovie.x = rcLeft.left;
  213.                   ptMovie.y = rcLeft.top;
  214.                   MCSetMovie (mcLeft, mLeft, hWnd, ptMovie);
  215.  
  216.                   ptMovie.x = rcRight.left;
  217.                   ptMovie.y = rcRight.top;
  218.                   MCSetMovie (mcRight, mRight, hWnd, ptMovie);
  219.  
  220.                // Pause the movies
  221.  
  222.                   MCDoAction (mcLeft, mcActionPlay, 0);
  223.                   MCDoAction (mcRight, mcActionPlay, 0);
  224.  
  225.                // Center the movies
  226.  
  227.                   MCPositionController (mcLeft, &rcLeft,
  228.                      NULL, mcTopLeftMovie + mcScaleMovieToFit);
  229.                   MCPositionController (mcRight, &rcRight,
  230.                      NULL, mcTopLeftMovie + mcScaleMovieToFit);
  231.  
  232.                // Make the controllers visible
  233.  
  234.                   MCSetVisible (mcLeft, TRUE);
  235.                   MCSetVisible (mcRight, TRUE);
  236.  
  237.                // Make both movies active and the right mc inactive
  238.  
  239.                   SetMovieActive (mLeft, TRUE);
  240.                   SetMovieActive (mRight, TRUE);
  241.                   MCActivate (mcRight, hWnd, FALSE);
  242.  
  243.                // Eliminate the grow boxes
  244.  
  245.                   SetRectEmpty (&rcGrowBox);
  246.                   MCDoAction (mcLeft, mcActionSetGrowBoxBounds, &rcGrowBox);
  247.                   MCDoAction (mcRight, mcActionSetGrowBoxBounds, &rcGrowBox);
  248.                   }
  249.                return 0;
  250.  
  251.       // Change active controller to attached
  252.  
  253.             case IDM_ATTACH:
  254.  
  255.                MCSetControllerAttached (mcActive, TRUE);
  256.                return 0;
  257.  
  258.       // Change active controller to detached
  259.  
  260.             case IDM_DETACH:
  261.                {
  262.                RECT rcMCRect;
  263.                short sMCHeight;
  264.  
  265.             // Detach the controller
  266.  
  267.                MCSetControllerAttached (mcActive, FALSE);
  268.  
  269.             // Choose the appropriate movie/movie controller
  270.  
  271.                if (mcActive == mcLeft)
  272.                   {
  273.  
  274.                // Get the bounds rect for the controller only
  275.                // since it is now detached
  276.  
  277.                   MCGetControllerBoundsRect (mcLeft, &rcMCRect);
  278.                   OffsetRect (&rcMCRect, -rcMCRect.left, -rcMCRect.top);
  279.  
  280.                // Save the controller height
  281.  
  282.                   sMCHeight = rcMCRect.bottom - rcMCRect.top;
  283.  
  284.                // Move the controller down
  285.  
  286.                   memcpy (&rcMCRect, &rcLeft, sizeof (RECT));
  287.                   rcMCRect.top = rcLeft.bottom + (rcMovieBox.bottom / 2);
  288.                   rcMCRect.bottom = rcMCRect.top + sMCHeight;
  289.                   MCPositionController (mcLeft, &rcLeft, &rcMCRect,
  290.                      mcTopLeftMovie);
  291.                   }
  292.  
  293.                else
  294.                   {
  295.  
  296.                // Get the bounds rect for the controller only
  297.                // since it is now detached
  298.  
  299.                   MCGetControllerBoundsRect (mcRight, &rcMCRect);
  300.                   OffsetRect (&rcMCRect, -rcMCRect.left, -rcMCRect.top);
  301.  
  302.                // Save the controller height
  303.  
  304.                   sMCHeight = rcMCRect.bottom - rcMCRect.top;
  305.  
  306.                // Move the controller down
  307.  
  308.                   memcpy (&rcMCRect, &rcRight, sizeof (RECT));
  309.                   rcMCRect.top = rcRight.bottom + (rcMovieBox.bottom / 2);
  310.                   rcMCRect.bottom = rcMCRect.top + sMCHeight;
  311.                   MCPositionController (mcRight, &rcRight, &rcMCRect,
  312.                      mcTopLeftMovie);
  313.                   }
  314.                }
  315.                return 0;
  316.             }
  317.             return 0;
  318.  
  319.    // Center the controllers in the left and right halves of the window
  320.  
  321.       case WM_SIZE:
  322.  
  323.       // Attach the controllers
  324.  
  325.          MCSetControllerAttached (mcLeft, TRUE);
  326.          MCSetControllerAttached (mcRight, TRUE);
  327.  
  328.          CalcSize (hWnd);
  329.          MCSetControllerBoundsRect (mcLeft, &rcLeft);
  330.          MCSetControllerBoundsRect (mcRight, &rcRight);
  331.          return 0;
  332.  
  333.  
  334.       case WM_LBUTTONDOWN:
  335.          {
  336.          SFIXED sfxVolume;
  337.  
  338.       // Activate the controller selected by the mouse click
  339.  
  340.          GetClientRect (hWnd, &rcClient);
  341.          bLeft = (short) (LOWORD (lParam)) < ((rcClient.right - rcClient.left) / 2);
  342.          mcActive = bLeft ? mcLeft : mcRight;
  343.          MCActivate (mcLeft, hWnd, bLeft);
  344.          MCActivate (mcRight, hWnd, !bLeft);
  345.  
  346.       // Disable sound and keyboard interface for appropriate controller
  347.  
  348.          if (mcActive == mcLeft)
  349.             {
  350.             MCDoAction (mcRight, mcActionGetVolume, (LPVOID) &sfxVolume);
  351.             sfxVolume = - (abs (sfxVolume));
  352.             MCDoAction (mcRight, mcActionSetVolume, (LPVOID) sfxVolume);
  353.  
  354.             MCDoAction (mcRight, mcActionSetKeysEnabled, (LPVOID) FALSE);
  355.             }
  356.  
  357.          else
  358.             {
  359.             MCDoAction (mcLeft, mcActionGetVolume, (LPVOID) &sfxVolume);
  360.             sfxVolume = - (abs (sfxVolume));
  361.             MCDoAction (mcLeft, mcActionSetVolume, (LPVOID) sfxVolume);
  362.  
  363.             MCDoAction (mcLeft, mcActionSetKeysEnabled, (LPVOID) FALSE);
  364.             }
  365.  
  366.       // Enable sound and keyboard for active controller
  367.  
  368.          MCDoAction (mcActive, mcActionGetVolume, (LPVOID) &sfxVolume);
  369.          sfxVolume = abs (sfxVolume);
  370.          MCDoAction (mcActive, mcActionSetVolume, (LPVOID) sfxVolume);
  371.  
  372.          MCDoAction (mcActive, mcActionSetKeysEnabled, (LPVOID) TRUE);
  373.          }
  374.          return 0;
  375.  
  376.    // Repaint the Window
  377.  
  378.       case WM_PAINT:
  379.  
  380.          if (!BeginPaint (hWnd, &ps))
  381.             return 0;
  382.          EndPaint (hWnd, &ps);
  383.          return 0;
  384.  
  385.    // Destroy the movies and controllers when the window is destroyed
  386.  
  387.       case WM_DESTROY:
  388.  
  389.          DisposeMovieController (mcLeft);
  390.          DisposeMovieController (mcRight);
  391.          DisposeMovie (mLeft);
  392.          DisposeMovie (mRight);
  393.          PostQuitMessage (0);
  394.          return 0;
  395.       }
  396.  
  397. // Return to Windows
  398.  
  399.    return DefWindowProc (hWnd, message, wParam, lParam);
  400.    }
  401.  
  402.  
  403. VOID CalcSize (HWND hWndCaller)
  404.    {
  405.    RECT rcBounds;
  406.  
  407.    GetClientRect (hWndCaller, &rcClient);
  408.  
  409.    MCGetControllerBoundsRect (mcLeft, &rcBounds);
  410.    OffsetRect (&rcBounds, -rcBounds.left, -rcBounds.top);
  411.  
  412.    rcLeft.top = rcRight.top = rcClient.top +
  413.       (rcClient.bottom / 2) - (rcBounds.bottom / 2);
  414.  
  415.    rcLeft.bottom = rcRight.bottom = rcClient.top +
  416.       (rcClient.bottom / 2) + (rcBounds.bottom / 2);
  417.  
  418.    rcLeft.left = (rcClient.right / 4) - (rcBounds.right / 2);
  419.    rcLeft.right = (rcClient.right / 4) + (rcBounds.right / 2);
  420.  
  421.    MCGetControllerBoundsRect (mcRight, &rcBounds);
  422.    OffsetRect (&rcBounds, -rcBounds.left, -rcBounds.top);
  423.  
  424.    rcRight.left = (rcClient.right / 2) + (rcClient.right / 4)
  425.       - (rcBounds.right / 2);
  426.    rcRight.right = (rcClient.right / 2) + (rcClient.right / 4)
  427.       + (rcBounds.right / 2);
  428.    }
  429.  
  430.